import sys

sys.path.append("..")
import enum

from PyQt5.QtCore import pyqtSignal, pyqtSlot
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import *

from common.qt_worker import Worker
from common.utils import decode_data
from ui.Ui_bluetooth import Ui_BluetoothWidget
from drivers.driver_bluetooth import BluetoothDataTransfer


class BluetoothState(enum.Enum):
    NORMAL = 0    # 未连接
    SCANNING = 1        # 扫描中
    CONNECTING = 2      # 连接中
    CONNECTED = 3       # 已连接


class BluetoothWidget(QWidget):
    # scan_devices_signal = pyqtSignal(list)

    def __init__(self, parent = None):
        super().__init__()
        self.ui = Ui_BluetoothWidget()
        self.ui.setupUi(self)

        self.bluetooth_state = BluetoothState.NORMAL

        # self.scan_devices_signal.connect(self.__on_scan_devices_signal)
        self.devices_list = []
        self.cur_transfer: BluetoothDataTransfer = None
        self.recv_worker: Worker = None

        self.init_ui()
        self.init_data()

    def connect_device(self):
        if self.cur_transfer is not None:
            self.disconnect_device()
            return

        index = self.ui.cb_devices.currentIndex()
        if index < 0:
            QMessageBox.information(self, "提示", "请先选择一个蓝牙设备")
            return

        device = self.devices_list[index]

        self.update_ui(BluetoothState.CONNECTING)

        addr, name = device
        transfer = BluetoothDataTransfer(addr, name)
        if transfer.connect():
            self.cur_transfer = transfer
            self.update_ui(BluetoothState.CONNECTED)
            
            # 开启循环接收子任务
            self.recv_worker = Worker(self.__on_recv_data)
            self.recv_worker.signal_connect(
                msg_handler=self.on_new_msg_received,
                finished_handler=self.disconnect_device
            )
            self.recv_worker.start()
        else:
            self.update_ui(BluetoothState.NORMAL)

    def disconnect_device(self):
        if self.cur_transfer is not None:
            self.cur_transfer.disconnect()
            self.cur_transfer = None
            self.recv_worker = None
            
        self.update_ui(BluetoothState.NORMAL)

    def on_new_msg_received(self, data: str):
        # self.ui.text_recv.append(msg)
        # print("msg: ", msg)
        self.ui.edit_recv.appendPlainText(decode_data(data))

    def __on_recv_data(self, worker: Worker):
        while worker.is_running:
            if self.cur_transfer is None:
                break
            data = self.cur_transfer.receive_data()
            if data:
                worker.emit_msg(data)
            else:
                break


    def update_ui(self, state: BluetoothState):
        self.bluetooth_state = state

        if state == BluetoothState.NORMAL:
            self.ui.btn_refresh.setEnabled(True)
            self.ui.btn_connect.setEnabled(True)
            self.ui.btn_connect.setText("连接蓝牙")
            self.ui.label_connect_state.setPixmap(QPixmap(":/icon/disc"))
        elif state == BluetoothState.SCANNING:
            self.ui.btn_refresh.setEnabled(False)
            self.ui.btn_connect.setEnabled(False)
            self.ui.btn_connect.setText("正在扫描...")
        elif state == BluetoothState.CONNECTING:
            self.ui.btn_refresh.setEnabled(False)
            self.ui.btn_connect.setEnabled(False)
            self.ui.btn_connect.setText("正在连接...")
        elif state == BluetoothState.CONNECTED:
            self.ui.btn_refresh.setEnabled(True)
            self.ui.btn_connect.setEnabled(True)
            self.ui.btn_connect.setText("已连接（点击断开）")
            self.ui.label_connect_state.setPixmap(QPixmap(":/icon/conn"))

        self.ui.box_device.setHidden(state != BluetoothState.CONNECTED)

        if self.cur_transfer is not None:
            self.ui.label_name.setText("名称：" + self.cur_transfer.target_name)
            self.ui.label_addr.setText("地址：" + self.cur_transfer.target_address)

    def init_ui(self):
        self.ui.btn_refresh.clicked.connect(self.refresh_devices)
        self.ui.btn_connect.clicked.connect(self.connect_device)
        self.ui.btn_send.clicked.connect(self.on_send_click)

        self.ui.box_device.setHidden(True)

    def init_data(self):
        pass

    def show_status_msg(self, msg):
        window = self.parent()
        if isinstance(window, QMainWindow):
            window.statusBar().showMessage(msg)

    def on_send_click(self):
        text = self.ui.edit_send.toPlainText()
        print("send: ", text)
        rst = self.cur_transfer.send_data(text)
        send_rst = "发送成功" if rst else "发送失败"

        self.show_status_msg(send_rst)

    @pyqtSlot(object)
    def __on_scan_devices_signal(self, devices):
        self.devices_list = devices
        self.show_status_msg("扫描完成")

        self.ui.cb_devices.clear()
        self.ui.cb_devices.addItems([name for addr, name in devices])
        
        self.update_ui(BluetoothState.NORMAL)
        # 展开下拉框
        # self.ui.cb_devices.showPopup()

    # def scan_all_devices(self):
    # devices = BluetoothDataTransfer.scan_devices()
    # self.scan_devices_signal.emit(devices)

    def refresh_devices(self):
        # 开启子线程扫描设备
        self.ui.cb_devices.clear()
        self.devices_list.clear()
        self.show_status_msg("正在扫描设备...")
        self.update_ui(BluetoothState.SCANNING)

        # thread = threading.Thread(target=self.scan_all_devices, daemon=True)
        # thread.start()
        worker = Worker(BluetoothDataTransfer.scan_devices)
        worker.signal_connect(result_handler=self.__on_scan_devices_signal)
        worker.start()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    
    w = BluetoothWidget()
    w.show()
    
    app.exit(app.exec_())
